/**
 * 应用初始化模块
 * 使用函数式编程组织应用启动逻辑
 * @author LYC
 * @date 2025-09-13
 */

import { app, BrowserWindow } from 'electron'
import { electronApp, optimizer } from '@electron-toolkit/utils'
import { resolve } from 'path'
import { AppExitManager } from './appExit'
import { AuthManager } from '../manager/authManager'
import { MenuManager } from '../manager/dockTrayManager'
import { IPCManager } from '../manager/ipcManager'
import { WindowFactory } from '../windowFactory'
import { ThemeManager } from '../manager/themeManager'
import { getNotificationManager } from '../manager/notificationManager'

/**
 * 应用配置接口
 */
export interface AppConfig {
  basic: {
    name: string
    version: string
    description: string
    author: string
  }
  window: {
    loginWidth: number
    loginHeight: number
    mainWidth: number
    mainHeight: number
    minWidth: number
    minHeight: number
  }
  icon: string
}

/**
 * 管理器实例接口
 */
export interface ManagerInstances {
  exitManager: AppExitManager
  authManager: AuthManager
  menuManager: MenuManager
  ipcManager: IPCManager
  windowFactory: WindowFactory
  themeManager?: ThemeManager
  notificationManager?: ReturnType<typeof getNotificationManager>
}

/**
 * 创建Electron应用基础设置的纯函数
 */
export const setupElectronApp = (): void => {
  electronApp.setAppUserModelId('com.electron')

  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })
}

/**
 * 创建应用事件监听器的工厂函数
 */
export const createAppEventListeners = (
  exitManager: AppExitManager,
  createLoginWindow: () => BrowserWindow
): Record<string, () => void> => ({
  beforeQuit: () => {
    console.log('App before-quit event triggered')
    if (!exitManager.isApplicationQuitting()) {
      console.log('Setting quit flag to allow window closing')
      exitManager.setQuittingFlag(true)
    }
  },

  activate: () => {
    exitManager.handleAppActivation(createLoginWindow)
  },

  windowAllClosed: () => {
    exitManager.handleAllWindowsClosed()
  }
})

/**
 * 注册应用事件监听器的纯函数
 */
export const registerAppEvents = (listeners: ReturnType<typeof createAppEventListeners>): void => {
  app.on('before-quit', listeners.beforeQuit)
  app.on('activate', listeners.activate)
  app.on('window-all-closed', listeners.windowAllClosed)
}

/**
 * 创建初始化步骤的函数数组
 */
export const createInitializationSteps = (
  config: AppConfig,
  managers: ManagerInstances,
  windowCreators: {
    createLoginWindow: () => BrowserWindow
    createMainWindow: () => BrowserWindow
  }
): Array<() => void> => [
  // 步骤1: 设置Electron应用
  () => {
    console.log('Step 1: Setting up Electron app...')
    setupElectronApp()
  },

  // 步骤2: 初始化IPC处理器
  () => {
    console.log('Step 2: Initializing IPC handlers...')
    managers.ipcManager.initializeHandlers(config.basic)

    // 初始化主题处理器
    if (managers.themeManager) {
      console.log('Initializing theme handlers...')
      managers.themeManager.initializeHandlers()
    }

    // 初始化通知管理器
    if (managers.notificationManager) {
      console.log('Initializing notification manager...')
      // 设置默认图标
      try {
        // 确保使用正确的绝对路径，指向项目中的Logo.png
        const appPath = app.getAppPath()
        console.log('应用路径:', appPath)
        // 在开发模式和生产模式下路径不同
        // 在开发模式下，appPath为项目根目录，如/Users/lyc/Desktop/XLChat
        const notificationIconPath = app.isPackaged
          ? resolve(process.resourcesPath, 'Logo.png') // 打包后使用资源目录
          : resolve(appPath, 'resources/Logo.png') // 开发模式下直接使用项目根目录
        console.log('设置通知默认图标:', notificationIconPath)
        managers.notificationManager.setDefaultIcon(notificationIconPath)
      } catch (error) {
        console.error('设置通知默认图标失败:', error)
        // 回退使用配置图标
        managers.notificationManager.setDefaultIcon(config.icon)
      }

      // 注册应用焦点变化事件
      app.on('browser-window-focus', () => {
        if (managers.notificationManager) {
          managers.notificationManager.setApplicationFocused(true)
        }
      })

      app.on('browser-window-blur', () => {
        if (managers.notificationManager) {
          managers.notificationManager.setApplicationFocused(false)
        }
      })

      console.log('Notification manager initialized successfully')
    }
  },

  // 步骤3: 初始化菜单
  () => {
    console.log('Step 3: Initializing menus...')
    managers.menuManager.initializeMenus(config.icon)
  },

  // 步骤4: 创建初始登录窗口
  () => {
    console.log('Step 4: Creating login window...')
    windowCreators.createLoginWindow()
  },

  // 步骤5: 注册应用事件
  () => {
    console.log('Step 5: Registering app events...')
    const listeners = createAppEventListeners(
      managers.exitManager,
      windowCreators.createLoginWindow
    )
    registerAppEvents(listeners)
  }
]

/**
 * 执行初始化步骤的纯函数
 */
export const executeInitializationSteps = (steps: (() => void)[]): void => {
  steps.forEach((step, index) => {
    try {
      step()
      console.log(`✓ Initialization step ${index + 1} completed`)
    } catch (error) {
      console.error(`✗ Initialization step ${index + 1} failed:`, error)
      throw error
    }
  })
}

/**
 * 应用初始化器类（函数式风格）
 */
export class AppInitializer {
  private static instance: AppInitializer
  private config: AppConfig
  private managers: ManagerInstances
  private isInitialized = false

  private constructor(config: AppConfig, managers: ManagerInstances) {
    this.config = config
    this.managers = managers
  }

  public static getInstance(config: AppConfig, managers: ManagerInstances): AppInitializer {
    if (!AppInitializer.instance) {
      AppInitializer.instance = new AppInitializer(config, managers)
    }
    return AppInitializer.instance
  }

  /**
   * 初始化应用的主方法
   */
  public initialize = (windowCreators: {
    createLoginWindow: () => BrowserWindow
    createMainWindow: () => BrowserWindow
  }): Promise<void> => {
    if (this.isInitialized) {
      console.log('App already initialized')
      return Promise.resolve()
    }

    return new Promise((resolve, reject) => {
      app
        .whenReady()
        .then(() => {
          try {
            console.log('🚀 Starting application initialization...')

            // 创建初始化步骤
            const steps = createInitializationSteps(this.config, this.managers, windowCreators)

            // 执行初始化步骤
            executeInitializationSteps(steps)

            this.isInitialized = true
            console.log('✅ Application initialization completed successfully!')
            resolve()
          } catch (error) {
            console.error('❌ Application initialization failed:', error)
            reject(error)
          }
        })
        .catch(reject)
    })
  }

  /**
   * 检查是否已初始化
   */
  public isAppInitialized = (): boolean => this.isInitialized

  /**
   * 获取配置信息
   */
  public getConfig = (): AppConfig => this.config

  /**
   * 获取管理器实例
   */
  public getManagers = (): ManagerInstances => this.managers

  /**
   * 清理应用资源
   */
  public cleanup = (): void => {
    console.log('🧹 Starting application cleanup...')

    // 清理各个管理器
    this.managers.ipcManager.cleanup()
    this.managers.menuManager.cleanup()
    this.managers.authManager.cleanup()
    // exitManager 不需要清理

    // 清理通知管理器
    if (this.managers.notificationManager) {
      this.managers.notificationManager.cleanup()
    }

    this.isInitialized = false
    console.log('✅ Application cleanup completed')
  }
}

/**
 * 创建应用初始化器的工厂函数
 */
export const createAppInitializer = (
  config: AppConfig,
  managers: ManagerInstances
): AppInitializer => {
  return AppInitializer.getInstance(config, managers)
}

/**
 * 创建完整的应用启动器的高阶函数
 */
export const createAppLauncher = (
  config: AppConfig
): ((
  managers: ManagerInstances,
  windowCreators: {
    createLoginWindow: () => BrowserWindow
    createMainWindow: () => BrowserWindow
  }
) => () => Promise<void>) => {
  return (
    managers: ManagerInstances,
    windowCreators: {
      createLoginWindow: () => BrowserWindow
      createMainWindow: () => BrowserWindow
    }
  ) => {
    const initializer = createAppInitializer(config, managers)
    return () => initializer.initialize(windowCreators)
  }
}
